package org.openaecfm.spf.io.constraint;

import java.util.ArrayList;

import org.openaecfm.model.constraint.Reference;
import org.openaecfm.spf.io.AbstractEntityInstanceInputImpl;
import org.openaecfm.spf.io.IAppDataManager;
import org.openaecfm.spf.io.IEntityInstanceOutput;
import org.openaecfm.spf.model.DollarParameter;
import org.openaecfm.spf.model.EntityInstance;
import org.openaecfm.spf.model.EntityInstanceNameParameter;
import org.openaecfm.spf.model.IntegerParameter;
import org.openaecfm.spf.model.ListParameter;
import org.openaecfm.spf.model.NodeType;
import org.openaecfm.spf.model.Parameter;
import org.openaecfm.spf.model.SimpleEntityInstance;
import org.openaecfm.spf.model.StringParameter;

public final class ReferenceIO extends
		AbstractEntityInstanceInputImpl<Reference> implements
		IEntityInstanceOutput<Reference> {

	@Override
	public String exportSPF(Reference pojo, IAppDataManager appDataManager) {
		SimpleEntityInstance ei = new SimpleEntityInstance("IFCREFERENCE",
				appDataManager.getName(pojo));

		// Set TypeIdentifier
		if (pojo.getTypeIdentifier() == null) {
			ei.addParameter(DollarParameter.getInstance());
		} else {
			ei.addParameter(new StringParameter(pojo.getTypeIdentifier(),
					StringParameter.UTF_8));
		}

		// Set AttributeIdentifier
		if (pojo.getAttributeIdentifier() == null) {
			ei.addParameter(DollarParameter.getInstance());
		} else {
			ei.addParameter(new StringParameter(pojo.getAttributeIdentifier(),
					StringParameter.UTF_8));
		}

		// Set InstanceName
		if (pojo.getInstanceName() == null) {
			ei.addParameter(DollarParameter.getInstance());
		} else {
			ei.addParameter(new StringParameter(pojo.getInstanceName(),
					StringParameter.UTF_8));
		}

		// Set ListPositions
		if (pojo.getListPositions() == null
				|| pojo.getListPositions().isEmpty()) {
			ei.addParameter(DollarParameter.getInstance());
		} else {
			ListParameter l = new ListParameter();
			for (Integer i : pojo.getListPositions()) {
				l.add(new IntegerParameter(i));
			}
			ei.addParameter(l);
		}

		// Set InnerReference
		if (pojo.getInnerReference() == null) {
			ei.addParameter(DollarParameter.getInstance());
		} else {
			ei.addParameter(new EntityInstanceNameParameter(appDataManager
					.getName(pojo.getInnerReference())));
		}

		return ei.toString();
	}

	@Override
	public void resolveReferenceParameter(EntityInstance ei, Reference pojo,
			IAppDataManager appDataManager) {
		SimpleEntityInstance sei = (SimpleEntityInstance) ei;

		// Set InnerReference
		Parameter inner = sei.getParameter(4);
		if (inner.getNodeType() == NodeType.ENTITY_INSTANCE_NAME) {
			EntityInstanceNameParameter e = (EntityInstanceNameParameter) inner;
			pojo.setInnerReference((Reference) appDataManager.getObject(e
					.toInstanceName()));
		}
	}

	@Override
	protected Reference doCreateObject() {
		return new Reference();
	}

	@Override
	protected void resolveNotReferenceParameter(EntityInstance ei,
			Reference pojo) {
		SimpleEntityInstance sei = (SimpleEntityInstance) ei;

		// Set TypeIdentifier
		Parameter typei = sei.getParameter(0);
		if (typei.getNodeType() == NodeType.STRING) {
			StringParameter s = (StringParameter) typei;
			pojo.setTypeIdentifier(s.toUTF8());
		}

		// Set AttributeIdentifier
		Parameter attr = sei.getParameter(1);
		if (attr.getNodeType() == NodeType.STRING) {
			StringParameter s = (StringParameter) attr;
			pojo.setAttributeIdentifier(s.toUTF8());
		}

		// Set InstanceName
		Parameter inname = sei.getParameter(2);
		if (inname.getNodeType() == NodeType.STRING) {
			StringParameter s = (StringParameter) inname;
			pojo.setInstanceName(s.toUTF8());
		}

		// Set ListPositions
		Parameter listp = sei.getParameter(3);
		if (listp.getNodeType() == NodeType.LIST) {
			ListParameter l = (ListParameter) listp;
			if (pojo.getListPositions() == null) {
				pojo.setListPositions(new ArrayList<Integer>());
			}
			for (Parameter p : l) {
				IntegerParameter i = (IntegerParameter) p;
				pojo.getListPositions().add(i.toInteger());
			}
		}
	}
}
